package mymongo

import (
    "fmt"
    "strconv"
    "mygo/mystruct"
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
)


/* =================================================================================
   获取数据库连接
*/
func Get_Code(code string) *Curs {
	clientsMu.Lock()
    defer clientsMu.Unlock()
	obj, ok := MyMonDB.DataCur[code]
	if (ok) {
		return &obj
	}
	res, ret := MyMonDB.ApiCur.Get(code)
	if res.Code == mystruct.MyCodeOk {
		mcur := Curs{
			Cur : MyMonDB.Database.Collection(ret.Api),
			Body: ret,
		}
		MyMonDB.DataCur[ret.Apiid] = mcur
		return &mcur
	}
	return nil
}

// 辅助函数：处理数值类型的条件
func handleNumericCondition(search *bson.D, key, op, value string) error {
    intValue, err := strconv.ParseInt(value, 10, 64)
    if err != nil {
        return err // 返回错误，避免无效值
    }

    switch op {
    case "0": // 大于
        *search = append(*search, bson.E{Key: key, Value: bson.M{"$gt": intValue}})
    case "1": // 小于
        *search = append(*search, bson.E{Key: key, Value: bson.M{"$lt": intValue}})
    case "2": // 等于
        *search = append(*search, bson.E{Key: key, Value: bson.M{"$eq": intValue}})
    }
    return nil
}

// 辅助函数：处理布尔类型的条件
func handleBoolCondition(search *bson.D, key, op string) error {
    switch op {
    case "0": // 真
        *search = append(*search, bson.E{Key: key, Value: true})
    case "1": // 假
        *search = append(*search, bson.E{Key: key, Value: false})
    default:
        return fmt.Errorf("invalid boolean operator: %s", op)
    }
    return nil
}

// 辅助函数：处理标签或按钮类型的条件
func handleTagOrButCondition(search *bson.D, key, op, value string) error {
    switch op {
    case "0": // 等于
        *search = append(*search, bson.E{Key: key, Value: value})
    case "1": // 不等于
        *search = append(*search, bson.E{Key: key, Value: bson.M{"$ne": value}})
    default:
        return fmt.Errorf("invalid tag/button operator: %s", op)
    }
    return nil
}

// 辅助函数：处理字符串或文件类型的条件
func handleStringOrFileCondition(search *bson.D, key, op, value string) {
    switch op {
    case "0": // 包含
        // 优化正则表达式：使用前缀匹配（如果可能）
        *search = append(*search, bson.E{Key: key, Value: bson.M{"$regex": primitive.Regex{Pattern: value, Options: "i"}}})
    case "1": // 不包含
        *search = append(*search, bson.E{Key: key, Value: bson.M{"$not": bson.M{"$regex": primitive.Regex{Pattern: value, Options: "i"}}}})
    case "2": // 等于
        *search = append(*search, bson.E{Key: key, Value: value})
    case "3": // 不等于
        *search = append(*search, bson.E{Key: key, Value: bson.M{"$ne": value}})
    }
}

func search_build(data map[string]interface{}, search *bson.D, client *Curs, model string) {
	for key, value := range data {
		item := mystruct.FindItemsByName(client.Body.Data, key)
        if item.Select == "" {
            continue
        }
        if value == "" {
        	continue
        }
        mkey := fmt.Sprintf("data.%s", key)
        switch item.Select {
            case "string", "file", "pack":
                handleStringOrFileCondition(search, mkey, model, value.(string))
            case "word":
            	*search = append(*search, bson.E{Key: fmt.Sprintf("%s.name", mkey), Value: value})
            default:
            	*search = append(*search, bson.E{Key: mkey, Value: value})
        }
    }
}